package com.sdy.supermarket.biz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.sdy.apigateway.api.AgInterfaceAuthApi;
import com.sdy.apigateway.api.dto.AgInterfaceAuthDTO;
import com.sdy.common.model.BizException;
import com.sdy.common.utils.Assert;
import com.sdy.common.utils.RandomUtil;
import com.sdy.common.utils.StringUtil;
import com.sdy.mvc.utils.JsonUtil;
import com.sdy.supermarket.biz.model.GsAppInterface;
import com.sdy.supermarket.biz.model.GsAppIpApply;
import com.sdy.supermarket.biz.model.GsSelfSystem;
import com.sdy.supermarket.biz.mapper.GsSelfSystemMapper;
import com.sdy.supermarket.biz.service.GsAppInterfaceService;
import com.sdy.supermarket.biz.service.GsAppIpApplyService;
import com.sdy.supermarket.biz.service.GsSelfSystemService;
import com.sdy.mvc.service.impl.BaseServiceImpl;
import com.sdy.supermarket.biz.vo.AppUpdateRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * <p>
 * 自建系统 服务实现类
 * </p>
 *
 * @author zzq
 * @since 2019-07-16
 */
@Slf4j
@Service
public class GsSelfSystemServiceImpl extends BaseServiceImpl<GsSelfSystem> implements GsSelfSystemService {
    @Autowired
    private GsSelfSystemMapper gsSelfSystemMapper;
    @Autowired
    private GsAppInterfaceService gsAppInterfaceService;
    @Autowired
    private AgInterfaceAuthApi agInterfaceAuthApi;
    @Autowired
    private GsAppIpApplyService gsAppIpApplyService;

    @Override
    public GsSelfSystem createSystem(GsSelfSystem gsSelfSystem) {
        String code = generateSelfSystemCode();
        save(gsSelfSystem.setCode(code));
        return gsSelfSystem;
    }

    @Override
    public void updateSystem(GsSelfSystem gsSelfSystem) throws BizException {
        // 只允许修改正常状态的 系统
        boolean success = update(gsSelfSystem.setModifyTime(null),
                new LambdaQueryWrapper<GsSelfSystem>()
                        .eq(GsSelfSystem::getState, 0)
                        .eq(GsSelfSystem::getUserId, gsSelfSystem.getUserId())
                        .eq(GsSelfSystem::getId, gsSelfSystem.getId()));
        Assert.isTrue(success, "更新失败");
        // 修改了默认系统，则需要将该用户的其他系统设置未非默认
        if (gsSelfSystem.getDef().equals(1)){
            update(new GsSelfSystem().setDef(0),
                    new LambdaQueryWrapper<GsSelfSystem>()
                            .eq(GsSelfSystem::getState, 0)
                            .eq(GsSelfSystem::getUserId, gsSelfSystem.getUserId())
                            .ne(GsSelfSystem::getId, gsSelfSystem.getId()));
        }
    }

    @Override
    public GsSelfSystem getByCode(String code) {
        if (StringUtil.isNotBlank(code)) {
            return getOne(new LambdaQueryWrapper<GsSelfSystem>().eq(GsSelfSystem::getCode, code));
        }
        return null;
    }

    @Override
    public List<GsAppInterface> listApiByCodeAndIp(String code, String ip) {
        List<GsAppInterface> appInterfaceList = gsAppInterfaceService.list(
                new LambdaQueryWrapper<GsAppInterface>().eq(GsAppInterface::getAppCode, code)
        );
        if (appInterfaceList.isEmpty()) {
            return new ArrayList<>();
        }
        List<AgInterfaceAuthDTO> apiAuthList = agInterfaceAuthApi.listByCodeAndIp(code, ip).getData();
        List<Integer> resIdList = apiAuthList.stream().map(AgInterfaceAuthDTO::getResId).collect(Collectors.toList());
        appInterfaceList.forEach(item -> item.setEnabled(resIdList.contains(item.getResId())));
        return null;
    }

    @Override
    public void removeIpAuth(String code, String ip) {
        agInterfaceAuthApi.removeIpAuth(code, ip);
    }

    @Override
    public void updateIpAuth(AppUpdateRequest appUpdateRequest, Integer userId) throws BizException {
        if (appUpdateRequest.getIpUpdateSubRequestList() == null) {
            appUpdateRequest.setIpUpdateSubRequestList(new ArrayList<>());
        }
        GsSelfSystem selfSystem = getByCode(appUpdateRequest.getCode());
        Assert.isNull(selfSystem, "自建系统不存在");
        Assert.isTrue(!selfSystem.getUserId().equals(userId), "没有修改权限");
        List<String> ipList = Arrays.stream(selfSystem.getIp().split(","))
                .filter(StringUtil::isNotBlank)
                .collect(Collectors.toList());
        // 删除IP
        List<String> toDelIp = appUpdateRequest.getIpUpdateSubRequestList()
                .stream()
                .filter(item -> item.getType().equals(2) || item.getType().equals(3))
                .map(AppUpdateRequest.IpUpdateSubRequest::getOriginIp)
                .collect(Collectors.toList());
        if (!toDelIp.isEmpty()) {
            ipList.removeAll(toDelIp);
        }
        // 增加IP
        List<String> toAddIp = appUpdateRequest.getIpUpdateSubRequestList()
                .stream()
                .filter(item -> item.getType().equals(1) || item.getType().equals(3))
                .map(AppUpdateRequest.IpUpdateSubRequest::getNewIp)
                .collect(Collectors.toList());
        if (!toDelIp.isEmpty()) {
            ipList.addAll(toDelIp);
        }
        // 是否需要提交申请单
        boolean needApply = appUpdateRequest.getIpUpdateSubRequestList().stream()
                .anyMatch(item -> item.getType().equals(1)
                        || item.getType().equals(3)
                        || (item.getType().equals(4) && !CollectionUtils.isEmpty(item.getAddApiList()))
                );
        if (needApply) {
            // 提交申请单
            gsAppIpApplyService.save(
                    new GsAppIpApply().setUserId(userId)
                            .setContent(JsonUtil.toJson(appUpdateRequest))
                            .setCreateTime(new Date())
                            .setState(1)
            );
        } else {
            // 移除IP
            appUpdateRequest.getIpUpdateSubRequestList().stream()
                    .filter(item -> item.getType().equals(2))
                    .forEach(item -> {
                        agInterfaceAuthApi.removeIpAuth(appUpdateRequest.getCode(), item.getOriginIp());
                    });
            // 移除IP中的某几个API
            appUpdateRequest.getIpUpdateSubRequestList().stream()
                    .filter(item -> item.getType().equals(4))
                    .filter(item -> !CollectionUtils.isEmpty(item.getDelApiList()))
                    .forEach(item -> {
                        agInterfaceAuthApi.removeIpAuthItem(
                                appUpdateRequest.getCode(),
                                item.getOriginIp(),
                                item.getDelApiList()
                        );
                    });
        }
        // 更新基本参数
        lambdaUpdate()
                .eq(GsSelfSystem::getCode, appUpdateRequest.getCode())
                .eq(GsSelfSystem::getUserId, userId)
                .set(GsSelfSystem::getName, appUpdateRequest.getName())
                .set(GsSelfSystem::getContent, appUpdateRequest.getContent())
                .set(GsSelfSystem::getDef, appUpdateRequest.getDef())
                .set(GsSelfSystem::getIp, String.join(",", ipList))
                .update();
    }

    /**
     * 生成自建系统编号
     */
    private String generateSelfSystemCode() {
        return UUID.randomUUID().toString();
    }
}
